package com.codeest.geeknews.util.convert;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * http://blog.csdn.net/wolfofsiberian/article/details/53192478
 * Created by admin on 2017/8/7.
 */

public class ObjectConvertor {
    public <K, V> V convertBean(K source, Class<V> target) {
        return convertBean(source, target, null);
    }

    public <K, V> V convertBean(K source, Class<V> target, Filter filter) {
        V anotherObj = null;
        try {
            anotherObj = target.newInstance();
            Class<?> oneClassObj = source.getClass();
            Field[] fields = getMatchedFields(oneClassObj, filter);
            for (Field field : fields) {
                String fieldName = field.getName();
                String append = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
                String getMethodName = "get" + append;
                String setMethodName = "set" + append;
                Method getMethod = oneClassObj.getDeclaredMethod(getMethodName);
                getMethod.setAccessible(true);
                Object attrForOneObj = getMethod.invoke(source);
                Method setMethod = target.getDeclaredMethod(setMethodName, field.getType());
                setMethod.setAccessible(true);
                setMethod.invoke(anotherObj, attrForOneObj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return anotherObj;
    }

    private Field[] getMatchedFields(Class<?> classObj, Filter filter) {
        List<Field> matchedFields = new ArrayList<Field>();
        Field[] fields = classObj.getDeclaredFields();
        for (Field field : fields) {
            if (null == filter || filter.accept(field)) {
                matchedFields.add(field);
            }
        }

        return matchedFields.toArray(new Field[]{});
    }
}
